﻿using Materal.Extensions;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WinUITest.AttachedProperties
{
    public partial class EnumList
    {
        public static bool GetIsNullEnumType(DependencyObject sender) => (bool)sender.GetValue(IsNullEnumTypeProperty);
        public static void SetIsNullEnumType(DependencyObject sender, bool value) => sender.SetValue(IsNullEnumTypeProperty, value);
        public static readonly DependencyProperty IsNullEnumTypeProperty = DependencyProperty.RegisterAttached("IsNullEnumType", typeof(bool), typeof(EnumList), new PropertyMetadata(false));
        public static Type GetEnumType(DependencyObject sender) => (Type)sender.GetValue(EnumTypeProperty);
        public static void SetEnumType(DependencyObject sender, Type value) => sender.SetValue(EnumTypeProperty, value);
        public static readonly DependencyProperty EnumTypeProperty = DependencyProperty.RegisterAttached("EnumType", typeof(Type), typeof(EnumList), new PropertyMetadata(null, OnEnumTypeChanged));
        private static async void OnEnumTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is not ComboBox comboBox || e.NewValue is not Type targetType) return;
            await Task.Delay(100);
            List<ComboBoxItemViewModel> enumViews = [];
            ComboBoxItemViewModel? selectedItem = null;
            bool isNullEnumType = GetIsNullEnumType(sender);
            if (targetType.IsGenericType && targetType.GenericTypeArguments.Length == 1)
            {
                Type genericType = targetType.GenericTypeArguments.First();
                if (targetType != typeof(Nullable<>).MakeGenericType(genericType)) return;
                isNullEnumType = true;
                targetType = genericType;
            }
            if (!targetType.IsEnum) return;
            if (isNullEnumType)
            {
                ComboBoxItemViewModel enumViewModel = new(null);
                enumViews.Add(enumViewModel);
                selectedItem = enumViewModel;
            }
            foreach (Enum value in Enum.GetValues(targetType))
            {
                ComboBoxItemViewModel enumViewModel = new(value);
                if (comboBox.SelectedValue is not null && comboBox.SelectedValue.Equals(value))
                {
                    selectedItem = enumViewModel;
                }
                enumViews.Add(enumViewModel);
            }
            comboBox.ItemsSource = enumViews;
            comboBox.DisplayMemberPath = nameof(ComboBoxItemViewModel.Description);
            comboBox.SelectedValuePath = nameof(ComboBoxItemViewModel.Value);
            comboBox.SelectedItem = selectedItem;
        }
        private partial class ComboBoxItemViewModel(object? value)
        {
            public object? Value { get; } = value;
            public string Description { get; } = value?.GetDescriptionOrNull() ?? value?.ToString() ?? value?.GetType().Name ?? "未选择";
        }
    }
}
